//
//  SinaRefreshControl.swift
//  SinaWeibo
//
//  Created by 王朝阳 on 2016/10/30.
//  Copyright © 2016年 wangzhaoyang. All rights reserved.
//

import UIKit

//自定义下拉刷新的状态
private enum SinaRefreshType: Int {
    //下拉刷新状态
    case normal = 0
    //松手就刷新
    case pulling = 1
    //正在刷新
    case refreshing = 2
}

//控件的高度
private let SinaRefreshControlHeight: CGFloat = 50
//自定义下拉刷新控件
class SinaRefreshControl: UIControl {
    
    //声明变量记录当前刷新的控件
    private var currentScrollView: UIScrollView?
    //记录当前刷新状态
    private var sinaRefreshType: SinaRefreshType = .normal {
        didSet{
            switch sinaRefreshType {
            case .normal:
                print("下拉刷新")
                pullDowmImageView.isHidden = false
                UIView.animate(withDuration: 0.25, animations: {
                    //重置箭头
                    self.pullDowmImageView.transform = CGAffineTransform.identity
                })
                indicatorView.stopAnimating()
                messageLabel.text = "下拉刷新"
                
                //判断上一次的刷新状态是否是正在刷新,让刷新控件停留
                if oldValue == .refreshing {
                    UIView.animate(withDuration: 0.25, animations: { 
                        //设置停留位置
                        self.currentScrollView?.contentInset.top -= SinaRefreshControlHeight
                    })
                }
            case .pulling:
                print("松手就刷新")
                //掉转箭头的方向,设置提示内容为松手就刷新
                UIView.animate(withDuration: 0.25, animations: { 
                    self.pullDowmImageView.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI))
                })
                messageLabel.text = "松手就刷新"
     
            case .refreshing:
                print("正在刷新")
                //隐藏箭头,开启动画,设置内容
                pullDowmImageView.isHidden = true
                indicatorView.startAnimating()
                messageLabel.text = "正在刷新..."
                UIView.animate(withDuration: 0.25, animations: {
                    self.currentScrollView?.contentInset.top += SinaRefreshControlHeight
                })
                //通知外界刷新数据
                sendActions(for: .valueChanged)
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
        //获取屏幕的宽度
        let screcnWidth = UIScreen.main.bounds.size.width
        //设置控件 frame
        self.frame = CGRect(x: 0, y: -SinaRefreshControlHeight, width: screcnWidth, height: SinaRefreshControlHeight)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //MARK: - 获取父控件
    override func willMove(toSuperview newSuperview: UIView?) {
        
        //判断是否可以滚动的控件
        if let scrollView = newSuperview as? UIScrollView {
        //使用 kvo 监听 contentOffSet 的改变
            
            scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
            currentScrollView = scrollView
        }
    }
    //MARK: - kvo监听方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
//        print(currentScrollView?.contentOffset.y ?? "")
        guard let scrollView = currentScrollView else {
            return
        }
        //计算临界点
        let maxY = -(scrollView.contentInset.top + SinaRefreshControlHeight)
        //获取 y 轴的偏移量
        let contenOffSetY = scrollView.contentOffset.y
        //判断当前是否是拖动状态
        if scrollView.isDragging {
            //如果偏移量小于临界值,并且为下拉刷新状态
            if contenOffSetY < maxY && sinaRefreshType == .normal {
                //让状态更改为松手就刷新
                sinaRefreshType = .pulling
                print("松手就刷新")
            }else if contenOffSetY >= maxY && sinaRefreshType == .pulling {
                sinaRefreshType = .normal
                print("normal")
            }
        }else {
            //表示松手,只有 pulling 状态才能进入正在刷新
            if sinaRefreshType == .pulling {
                sinaRefreshType = .refreshing
                print("正在刷新")
            }
        }
    }
    //结束刷新
    func endRefreshing() {
        sinaRefreshType = .normal
    }
    
    //移除 kvo
    deinit {
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    //添加控件
    private func setupUI() {
        backgroundColor = SinaRandomColor()
        
        //1.添加控件
        addSubview(pullDowmImageView)
        addSubview(messageLabel)
        addSubview(indicatorView)
        
        //2.使用系统的约束方法添加约束
        //2.1首先要关闭系统的 autoresizing
        pullDowmImageView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        
        //2.2使用系统的方法添加约束
        addConstraint(NSLayoutConstraint(item: pullDowmImageView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -35))
        addConstraint(NSLayoutConstraint(item: pullDowmImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .leading, relatedBy: .equal, toItem: pullDowmImageView, attribute: .trailing, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: messageLabel, attribute: .centerY, relatedBy: .equal, toItem: pullDowmImageView, attribute: .centerY, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: pullDowmImageView, attribute: .centerX, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: pullDowmImageView, attribute: .centerY, multiplier: 1, constant: 0))
        
    }
    
    //MARK: - 懒加载控件
    //1.下拉箭头
    fileprivate lazy var pullDowmImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    //2.下拉刷新内容
    fileprivate lazy var messageLabel: UILabel = {
       let label = UILabel()
        label.text = "下拉刷新"
        label.font = UIFont.systemFont(ofSize: 11)
        label.textColor = UIColor.red
        return label
    }()
    //3.刷新控件
    fileprivate lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
    
}
